use std::sync::Arc;
use std::path::PathBuf;
use log::{info, warn, error};
use tokio::runtime::Runtime;
use lazy_static::lazy_static;

// 导入模拟的RustFS模块
use crate::mock_rustfs::{new_object_layer_fn, init_global_store, ObjectOptions};

// RustFS服务配置
pub struct RustFSConfig {
    pub endpoint: String,
    pub access_key: String,
    pub secret_key: String,
    pub bucket_name: String,
    pub region: String,
}

impl Default for RustFSConfig {
    fn default() -> Self {
        RustFSConfig {
            endpoint: "http://localhost:9000".to_string(),
            access_key: "minioadmin".to_string(),
            secret_key: "minioadmin".to_string(),
            bucket_name: "zenrs".to_string(),
            region: "us-east-1".to_string(),
        }
    }
}

// RustFS服务
pub struct RustFSService {
    config: RustFSConfig,
    runtime: Option<Runtime>,
    initialized: bool,
}

impl RustFSService {
    // 创建新的RustFS服务
    pub fn new(config: RustFSConfig) -> Result<Self, String> {
        // 初始化Tokio运行时
        let runtime = match Runtime::new() {
            Ok(rt) => rt,
            Err(err) => return Err(format!("Failed to initialize Tokio runtime: {}", err)),
        };

        Ok(RustFSService {
            config,
            runtime: Some(runtime),
            initialized: false,
        })
    }

    // 启动RustFS服务
    pub fn start(&mut self) -> Result<(), String> {
        if self.initialized {
            warn!("RustFS service already initialized");
            return Ok(());
        }

        info!("Starting RustFS service");

        // 初始化模拟存储
        init_global_store(&self.config.bucket_name);

        // 检查是否有可用的RustFS实例
        let runtime = self.runtime.as_ref().unwrap();
        let result = runtime.block_on(async {
            match new_object_layer_fn() {
                Some(_store) => {
                    // 初始化存储连接完成
                    Ok(())
                },
                None => Err("No RustFS object layer available".to_string()),
            }
        });

        if result.is_ok() {
            self.initialized = true;
            info!("RustFS service started successfully");
        } else {
            error!("Failed to start RustFS service: {:?}", result);
        }

        result
    }

    // 停止RustFS服务
    pub fn stop(&mut self) -> Result<(), String> {
        if !self.initialized {
            return Ok(());
        }

        info!("Stopping RustFS service");
        // 清理资源
        self.initialized = false;
        
        Ok(())
    }

    // 检查服务是否正在运行
    pub fn is_running(&self) -> bool {
        self.initialized
    }

    // 读取文件内容
    pub fn read_file(&self, path: &str) -> Result<Vec<u8>, String> {
        if !self.initialized {
            return Err("RustFS service not initialized".to_string());
        }

        let runtime = self.runtime.as_ref().unwrap();
        let path_clone = path.to_string();
        let bucket_name = self.config.bucket_name.clone();

        runtime.block_on(async move {
            match new_object_layer_fn() {
                Some(store) => {
                    // 构建完整的对象键
                    let object_key = path_clone.trim_start_matches('/');
                    
                    match store.get_object(&bucket_name, object_key, None).await {
                        Ok(data) => Ok(data),
                        Err(err) => Err(format!("Failed to read file {}: {:?}", path_clone, err)),
                    }
                },
                None => Err("No RustFS object layer available".to_string()),
            }
        })
    }

    // 写入文件内容
    pub fn write_file(&self, path: &str, content: &[u8]) -> Result<(), String> {
        if !self.initialized {
            return Err("RustFS service not initialized".to_string());
        }

        let runtime = self.runtime.as_ref().unwrap();
        let path_clone = path.to_string();
        let content_clone = content.to_vec();
        let bucket_name = self.config.bucket_name.clone();

        runtime.block_on(async move {
            match new_object_layer_fn() {
                Some(store) => {
                    // 构建完整的对象键
                    let object_key = path_clone.trim_start_matches('/');
                    
                    // 准备对象选项
                    let options = rustfs_ecstore::store_api::ObjectOptions::default();
                    
                    match store.put_object(&bucket_name, object_key, content_clone.into(), options).await {
                        Ok(_) => Ok(()),
                        Err(err) => Err(format!("Failed to write file {}: {:?}", path_clone, err)),
                    }
                },
                None => Err("No RustFS object layer available".to_string()),
            }
        })
    }

    // 创建目录
    pub fn create_directory(&self, path: &str) -> Result<(), String> {
        if !self.initialized {
            return Err("RustFS service not initialized".to_string());
        }

        let runtime = self.runtime.as_ref().unwrap();
        let path_clone = path.to_string();
        let bucket_name = self.config.bucket_name.clone();

        runtime.block_on(async move {
            match new_object_layer_fn() {
                Some(store) => {
                    // 在对象存储中，目录通常通过在路径末尾添加'/'来表示
                    let dir_key = format!("{}/", path_clone.trim_start_matches('/'));
                    
                    // 创建一个空对象来表示目录
                    let options = rustfs_ecstore::store_api::ObjectOptions::default();
                    
                    match store.put_object(&bucket_name, &dir_key, Vec::new().into(), options).await {
                        Ok(_) => Ok(()),
                        Err(err) => Err(format!("Failed to create directory {}: {:?}", path_clone, err)),
                    }
                },
                None => Err("No RustFS object layer available".to_string()),
            }
        })
    }

    // 删除文件或目录
    pub fn delete(&self, path: &str) -> Result<bool, String> {
        if !self.initialized {
            return Err("RustFS service not initialized".to_string());
        }

        let runtime = self.runtime.as_ref().unwrap();
        let path_clone = path.to_string();
        let bucket_name = self.config.bucket_name.clone();

        runtime.block_on(async move {
            match new_object_layer_fn() {
                Some(store) => {
                    let object_key = path_clone.trim_start_matches('/');
                    
                    // 检查是否是目录
                    let is_dir = object_key.ends_with('/');
                    
                    if is_dir {
                        // 对于目录，需要列出并删除所有对象
                        let prefix = object_key.to_string();
                        let objects = store.list_objects(&bucket_name, Some(&prefix), None, 1000).await;
                        
                        if let Ok(objects) = objects {
                            for obj in objects {
                                if let Err(err) = store.delete_object(&bucket_name, &obj.name).await {
                                    warn!("Failed to delete object {}: {:?}", obj.name, err);
                                }
                            }
                        }
                    }
                    
                    // 删除指定的对象或目录标记
                    match store.delete_object(&bucket_name, object_key).await {
                        Ok(_) => Ok(true),
                        Err(err) => Err(format!("Failed to delete {}: {:?}", path_clone, err)),
                    }
                },
                None => Err("No RustFS object layer available".to_string()),
            }
        })
    }

    // 列出目录内容（兼容方法）
    pub fn list(&self, path: &str) -> Result<Vec<String>, String> {
        self.list_directory(path)
    }

    // 列出目录内容
    pub fn list_directory(&self, path: &str) -> Result<Vec<String>, String> {
        if !self.initialized {
            return Err("RustFS service not initialized".to_string());
        }

        let runtime = self.runtime.as_ref().unwrap();
        let path_clone = path.to_string();
        let bucket_name = self.config.bucket_name.clone();

        runtime.block_on(async move {
            match new_object_layer_fn() {
                Some(store) => {
                    let prefix = path_clone.trim_start_matches('/');
                    let prefix_with_slash = if prefix.ends_with('/') {
                        prefix.to_string()
                    } else {
                        format!("{}/", prefix)
                    };
                    
                    match store.list_objects(&bucket_name, Some(&prefix_with_slash), None, 1000).await {
                        Ok(objects) => {
                            let mut entries = Vec::new();
                            for obj in objects {
                                // 提取文件名，去掉前缀
                                if let Some(name) = obj.name.strip_prefix(&prefix_with_slash) {
                                    if !name.is_empty() {
                                        entries.push(name.to_string());
                                    }
                                }
                            }
                            Ok(entries)
                        },
                        Err(err) => Err(format!("Failed to list directory {}: {:?}", path_clone, err)),
                    }
                },
                None => Err("No RustFS object layer available".to_string()),
            }
        })
    }
}

    // 检查文件或目录是否存在
    pub fn exists(&self, path: &str) -> bool {
        if !self.initialized {
            return false;
        }

        let runtime = self.runtime.as_ref().unwrap();
        let path_clone = path.to_string();
        let bucket_name = self.config.bucket_name.clone();

        runtime.block_on(async move {
            match new_object_layer_fn() {
                Some(store) => {
                    let object_key = path_clone.trim_start_matches('/');
                    
                    // 检查是否是目录
                    let (is_dir_key, check_key) = if object_key.ends_with('/') {
                        (true, object_key.to_string())
                    } else {
                        (false, format!("{}/", object_key))
                    };
                    
                    // 尝试直接获取对象
                    if !is_dir_key {
                        match store.get_object(&bucket_name, object_key, None).await {
                            Ok(_) => return true,
                            Err(_) => {}
                        }
                    }
                    
                    // 尝试列出目录
                    match store.list_objects(&bucket_name, Some(&check_key), None, 1).await {
                        Ok(objects) => !objects.is_empty(),
                        Err(_) => false
                    }
                },
                None => false
            }
        })
    }

    // 检查是否为目录
    pub fn is_directory(&self, path: &str) -> bool {
        if !self.initialized {
            return false;
        }

        let runtime = self.runtime.as_ref().unwrap();
        let path_clone = path.to_string();
        let bucket_name = self.config.bucket_name.clone();

        runtime.block_on(async move {
            match new_object_layer_fn() {
                Some(store) => {
                    let object_key = path_clone.trim_start_matches('/');
                    let prefix = if object_key.ends_with('/') {
                        object_key.to_string()
                    } else {
                        format!("{}/", object_key)
                    };
                    
                    // 检查是否存在目录标记文件
                    match store.get_object(&bucket_name, &prefix, None).await {
                        Ok(_) => return true,
                        Err(_) => {}
                    }
                    
                    // 检查是否有以该路径为前缀的对象
                    match store.list_objects(&bucket_name, Some(&prefix), None, 1).await {
                        Ok(objects) => !objects.is_empty(),
                        Err(_) => false
                    }
                },
                None => false
            }
        })
    }

    // 获取文件大小
    pub fn get_size(&self, path: &str) -> Option<u64> {
        if !self.initialized {
            return None;
        }

        let runtime = self.runtime.as_ref().unwrap();
        let path_clone = path.to_string();
        let bucket_name = self.config.bucket_name.clone();

        runtime.block_on(async move {
            match new_object_layer_fn() {
                Some(store) => {
                    let object_key = path_clone.trim_start_matches('/');
                    
                    match store.stat_object(&bucket_name, object_key).await {
                        Ok(metadata) => Some(metadata.size),
                        Err(_) => None
                    }
                },
                None => None
            }
        })
    }

impl Drop for RustFSService {
    fn drop(&mut self) {
        if self.is_running() {
            let _ = self.stop();
        }
        
        // 清理运行时
        if let Some(runtime) = self.runtime.take() {
            runtime.shutdown_background();
        }
    }
}